package util;

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User: tum0r
 * Package Name: util
 * Time: 2019-04-22 Monday 18:13:40
 */
public class JudgeSubject implements Runnable {
    private String recordID;
    private String userID;
    private String subjectID;
    private String language;
    private long timeLimit;
    private String testCase;
    private String testCaseResult;
    private GetRSS getRSS;

    private String format;

    private String result;
    private long time = 0;

    public void setResult(String result) {
        this.result = result;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public String getResult() {
        return result;
    }

    public String getFormat() {
        return format;
    }

    public void setThread(Thread thread) {
        getRSS.setThread(thread);
    }

    public JudgeSubject(String recordID, String userID, String subjectID, String language, long timeLimit, long memoryLimit, String testCase, String testCaseResult, String format, GetRSS getRSS) {
        this.recordID = recordID;
        this.userID = userID;
        this.subjectID = subjectID;
        this.language = language;
        this.timeLimit = timeLimit;
        this.testCase = testCase;
        this.testCaseResult = testCaseResult;
        this.format = format == null ? "" : format;
        this.result = "Time Limit Exceeded";

        this.getRSS = getRSS;
        this.getRSS.setLimitMemory(memoryLimit);
        this.getRSS.setJudgeSubject(this);
    }

    @Override
    public void run() {
        try {
            String path = "judge" + File.separator + userID + File.separator + subjectID + File.separator + recordID + File.separator;
            File folder = new File(path);
            Runtime runtime = Runtime.getRuntime();
            String[] run = new String[3];
            String codePath = folder.getAbsolutePath() + File.separator;
            if (language.equals("Java")) {
                run[0] = "java";
                run[1] = "-Xbootclasspath/a:" + codePath;
                run[2] = "Main";
            } else if (language.equals("C/CPP")) {
                run[0] = codePath + "./Main.out";
                run[1] = "";
                run[2] = "";
            } else {
                run[0] = "python3";
                run[1] = codePath + "Main.py";
                run[2] = "";
            }
            long t1, t2;
            Thread thread = new Thread(getRSS);
            t1 = System.currentTimeMillis();
            Process process = runtime.exec(run);
            getRSS.setPid(process.pid());
            thread.start();
            Thread.sleep(1000);
            if (!testCase.trim().equals("")) {
                OutputStream outputStream = process.getOutputStream();
                outputStream.write(testCase.getBytes());
                outputStream.flush();
                outputStream.close();
            }
            int state = process.waitFor();
            t2 = System.currentTimeMillis();
            time = t2 - t1 - 1000;

            if (state == 0) {
                if (time <= timeLimit) {
                    InputStream inputStream = process.getInputStream();
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                    StringBuilder outputResult = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        outputResult.append(line).append("\r\n");
                    }
                    bufferedReader.close();
                    inputStreamReader.close();
                    inputStream.close();
                    if (outputResult.toString().trim().equals(testCaseResult.trim())) {
                        result = "Accepted";
                    } else {
                        result = "Wrong Answer";
                        if (!format.equals("")) {
                            String[] outputResults = outputResult.toString().trim().split("\r\n");
                            Pattern pattern = Pattern.compile(format);
                            Matcher matcher;
                            for (int i = 0; i < outputResults.length; i++) {
                                matcher = pattern.matcher(outputResults[i]);
                                if (!matcher.find()) {
                                    result = "Presentation Error";
                                }
                            }
                        }
                    }
                }
            } else {
                result = "RunTime Error";
            }
        } catch (IOException |
                InterruptedException e) {
            e.printStackTrace();
        }
    }
}
